package com.sevenluo.netty.learn.client.handler;

import com.sevenluo.netty.learn.common.RequestMessage;
import com.sevenluo.netty.learn.common.keepalive.KeepAliveOperation;
import com.sevenluo.netty.learn.util.IdUtil;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * @author: 程序员七哥
 * @date: 2022-02-02
 * @description: 配合 write idle check 实现 keepalive 消息发送，5 秒没数据发就发送消息
 */
@Slf4j
@ChannelHandler.Sharable
public class KeepaliveHandler extends ChannelDuplexHandler {

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        /**
         * 为什么只判断第一次写空闲事件？
         *
         * 写keepalive 消息的时候（idleStateHandler#write）会回调：IdleStateHandler#writeListener
         * 然后重置了状态位：
         * firstWriterIdleEvent = firstAllIdleEvent = true;
         */
        if (evt == IdleStateEvent.FIRST_WRITER_IDLE_STATE_EVENT) {
            log.info("write idle check happen,so need message to server to keep connection not close");
            KeepAliveOperation keepAliveOperation = new KeepAliveOperation();
            RequestMessage requestMessage = new RequestMessage(IdUtil.nextId(),keepAliveOperation);
            ctx.writeAndFlush(requestMessage);

        }
        super.userEventTriggered(ctx, evt);
    }
}
